﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Mimoza.AgentLayer.Communication;
using Mimoza.Transport;

namespace Mimoza.ServiceLayer
{
    /// <summary>
    /// Class represent updates file repository. This class receive requests from terminals to updates files.
    /// </summary>
    class UpdatesFileRepository : BaseObject
    {
        public UpdatesFileRepository(Configuration config)
            : base(config)
        {
            RequestUpdatesFileChunk.RegisterHandler(
                new RequestUpdatesFileChunk.Handler(
                    ProcessFileChunkRequest));
        }

        ReplyUpdatesFileChunk ProcessFileChunkRequest(RequestUpdatesFileChunk request)
        {
            Common.Logger.Log.Info("UpdatesFileRepository updateId - '"
                + request.UpdateId.ToString() + "' pos - " + request.Position.ToString() + " ." );

            byte[] body = null;
            bool bEof = false;
            GetUpdatesFileChunk(request, ref body, ref bEof);

            ReplyUpdatesFileChunk reply = new ReplyUpdatesFileChunk(request.Position, body, bEof);
            return reply;
        }

        void GetUpdatesFileChunk(RequestUpdatesFileChunk request, ref byte[] body, ref bool bEof)
        {
            string updateFileName = GetUpdatesFileName(request.UpdateId);

            using (FileStream fs = File.Open(updateFileName, FileMode.Open))
            {
                fs.Seek(request.Position, SeekOrigin.Begin);

                byte[] readBuff = new byte[request.NeedSize];
                int nCount = fs.Read(readBuff, 0, request.NeedSize);
                if (nCount < 0)
                {
                    throw new AgentUpdatesFileError();
                }
                if (nCount < request.NeedSize)
                {
                    body = new byte[nCount];
                    Array.Copy(readBuff, body, nCount);

                    bEof = true;
                }
                else
                {
                    body = readBuff;
                }

            }
        }

        string GetUpdatesFileName(Guid updateId)
        {
            ObjectLayer.Update update = Configuration.ObjectLayer.UpdateRepository.GetUpdateByID(updateId);
            if (update==null)
            {
                throw new AgentUpdatesFileNotFound();
            }

            return update.UpdateFileName;
        }
    }
}
